package com.caird.pmp.iot.message;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.Data;

@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public abstract class MessageBase implements IMessage {

    public short getBodyLength() {
        return attr;
    }

    public void setBodyLength(short bodyLength) {
        attr = bodyLength;
    }

    protected int getMaxBodyLength() {
        return 64;
    }

    protected boolean encodeBody(ByteBuf rawMessage) {
        return false;
    }

    protected boolean decodeBody(ByteBuf rawMessage) {
        return false;
    }

    public ByteBuf encode() {

        ByteBuf raw = Unpooled.buffer(MESSAGE_BODY_WRAPPER_LENGTH + getMaxBodyLength());

        //分隔符
        raw.writeByte(0x7E);

        //消息ID
        raw.writeShort(id);

        //消息属性
        raw.writeShort(attr);

        //SIM卡号
        raw.writeBytes(MessageUtils.encodeBCD(simNo));

        //消息流水号
        raw.writeShort(flowNo);

        //消息体
        if (!encodeBody(raw))
            return null;

        //消息属性-重写
        setBodyLength((short)(raw.readableBytes() - 13));
        raw.markWriterIndex();
        raw.writerIndex(3);
        raw.writeShort(attr);
        raw.resetWriterIndex();

        //校验
        raw.writeByte(MessageUtils.xor(raw, 1, raw.readableBytes()));

        //分隔符
        raw.writeByte(0x7E);

        return raw;
    }


    public boolean decode(ByteBuf rawMessage) {

        ByteBuf raw;

        this.rawMessage = rawMessage;
        raw = rawMessage;
        if (null == raw)
            return false;

        raw.readerIndex(1);

        //消息ID
        id = raw.readShort();

        //消息体属性
        attr = raw.readShort();

        //sim卡号
        byte[] bs = new byte[6];
        raw.readBytes(bs);
        simNo = MessageUtils.decodeBCD(bs);

        //流水号
        flowNo = raw.readShort();

        //消息体
        return decodeBody(raw);
    }

    //消息ID
    protected short id;
    //消息体属性
    protected short attr;
    //SIM卡号：全局simNo变量统一为以0开头的11位卡号
    protected String simNo;
    //流水号
    protected short flowNo;
    //原始报文
    protected ByteBuf rawMessage;
}
